package com.general.framework.zzyy.juc;

/**
 * @Description: 双重检查锁单例模式
 * @Author: zzyy
 * @Date: 2024/11/28 20:22
 */
public class DoubleCheckSingleton {
    private static volatile DoubleCheckSingleton instance;
    // 构造方法私有化，防止外部通过new创建对象
    private DoubleCheckSingleton(){}
    // 双重检查锁
    public static DoubleCheckSingleton getInstance(){
        if(instance==null){
            // 1. 多线程并发创建对象时，会通过synchronized保证只有一个线程能创建对象
            synchronized(DoubleCheckSingleton.class){
                if(instance==null){
                    // 隐患：指令重排，可能会先分配对象内存空间，再初始化对象，导致其他线程获取到未初始化的对象
                    // 所以需要在instance声明的地方使用volatile关键字，禁止指令重排
                    instance = new DoubleCheckSingleton();
                }
            }
        }
        // 2. 创建对象后，执行getInstance方法将不再需要获取锁，直接返回对象
        return instance;
    }
}
// 👇👇👇
// 👇👇👇

// 现在比较好的做法是使用静态内部类的方式来实现单例模式，这种方式既保证了线程安全，又避免了性能问题。

// public class Singleton {
//     private Singleton() {}
//     private static class SingletonHolder {
//         private static final Singleton INSTANCE = new Singleton();
//     }
//     public static Singleton getInstance() {
//         return SingletonHolder.INSTANCE;
//     }
// }